/**
 * Copyright (c) Daniel Centore
 *
 * ex: set filetype=java expandtab tabstop=4 shiftwidth=4 :
 *
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation.
 */
package ronp.anim.gui.tools.drawing;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;

import ronp.anim.data.Grip;
import ronp.anim.data.filmstrip.Animation;
import ronp.anim.data.filmstrip.Layer;
import ronp.anim.data.objects.RNSimpleImage;
import ronp.anim.gui.SelectedState;
import ronp.anim.gui.tools.Tool;
import ronp.anim.gui.viewer.AnimViewer;
import ronp.anim.saving.SaveHandler;
import ronp.anim.undo.UndoController;

/**
 * Temporary throw-together image drawer. We will move onto more advanced versions later.
 * 
 * @author Daniel Centore
 *
 */
public class SimpleImageDrawer extends Tool
{
	private Grip start = null; // For starting from last grip
	private Point first = null; // The first point (null until selected)
	private Point second = null; // The second point (null until selected)

	private AnimViewer viewer;
	private Animation anim;
	private SelectedState state;
	private ImageIcon image;

	private UndoController undoController;

	public SimpleImageDrawer(AnimViewer viewer, Animation anim, SelectedState state, UndoController undoController)
	{
		JFileChooser choose = SaveHandler.fileChooser(SaveHandler.FILETYPE_IMAGES);
		int val = choose.showOpenDialog(null);
		if (val == JFileChooser.APPROVE_OPTION)
		{
			File k = choose.getSelectedFile();
			image = new ImageIcon(k.getAbsolutePath());
		}

		this.viewer = viewer;
		this.anim = anim;
		this.state = state;
		this.undoController = undoController;
	}

	@Override
	public void mousePressed(int x, int y)
	{
		// unused
	}

	@Override
	public void mouseReleased(int x, int y)
	{
		if (first == null && start == null)
			first = new Point(x, y);
		else if (start != null)
		{
			undoController.addMove();

			Layer l;
			second = new Point(x, y);
			Grip g1 = new Grip();
			g1.setPosition(0, second);
			anim.addLayer(l = new Layer(g1));

			anim.addObject(new RNSimpleImage(start, g1, image));

			start = g1;
			state.setActiveLayer(l);
			viewer.setTool(null);
		}
		else
		{
			undoController.addMove();

			Layer l;
			second = new Point(x, y);

			Grip g = new Grip();
			g.setPosition(0, first);
			anim.addLayer(new Layer(g));

			Grip g1 = new Grip();
			g1.setPosition(0, second);
			anim.addLayer(l = new Layer(g1));

			anim.addObject(new RNSimpleImage(g, g1, image));

			start = g1;
			state.setActiveLayer(l);
			viewer.setTool(null);
		}
	}

	@Override
	public void gripSelected(Layer l, int x, int y)
	{
		Grip g = l.getGrip();

		if (first == null && start == null)
			start = g;
		else if (start != null)
		{
			undoController.addMove();

			anim.addObject(new RNSimpleImage(start, g, image));

			start = g;
			state.setActiveLayer(l);
			viewer.setTool(null);
		}
		else if (first != null)
		{
			undoController.addMove();

			Grip g1 = new Grip();
			g1.setPosition(0, first);
			anim.addLayer(new Layer(g1));

			anim.addObject(new RNSimpleImage(g1, g, image));

			start = g;
			state.setActiveLayer(l);
			viewer.setTool(null);
		}
	}

	@Override
	public BufferedImage getOverlay(int x, int y)
	{
		BufferedImage image = new BufferedImage(anim.getWidth(), anim.getHeight(), BufferedImage.TYPE_INT_ARGB);
		if (first == null)
			return image;

		Image img = this.image.getImage();

		Graphics2D g2 = (Graphics2D) image.getGraphics();

		Point p1 = first;
		Point p2 = new Point(x, y);

		AffineTransform at = new AffineTransform();
		at.translate(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y));
		at.scale((double) Math.abs(p1.x - p2.x) / img.getWidth(null), (double) Math.abs(p1.y - p2.y) / img.getHeight(null));
		if (p2.x > p1.x)
		{
			at.translate(img.getWidth(null), 0);
			at.scale(-1, 1);
		}

		if (p2.y > p1.y)
		{
			at.translate(0, img.getHeight(null));
			at.scale(1, -1);
		}

		g2.drawImage(img, at, null);

		g2.dispose();

		return image;
	}

}
